#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "log.hpp"

enum
{
    SOCKET_ERR = 1,
    CONNECT_ERR,
};

void usage(const std::string& proc)
{
    std::cout << "\n\rUsage : " << proc << "ServerIp ServerPort\n" << std::endl;
}

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        usage(argv[0]);
        exit(0);
    }

    std::string server_ip = argv[1];
    uint16_t server_port = std::stoi(argv[2]); 




    // 系统会帮我们绑定

    // 链接服务器
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(server_port);
    server.sin_addr.s_addr = inet_addr(server_ip.c_str());



    std::string outbuffer;
    char inbuffer[4096];

    while(1)
    {
        int cnt = 100;
        bool is_reconnect = 0;

        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(sockfd < 0)
        {
            lg(Fatal, "sockfd error, errno: %d, error string: %s", errno, strerror(errno));
            exit(SOCKET_ERR);
        }

        do
        {
            int n = connect(sockfd, (struct sockaddr*)&server, sizeof(server));
            if(n < 0)
            {
                cnt--;
                is_reconnect = 1;
                std::cerr << "connect error..., reconnect: " << cnt << std::endl;
                sleep(2);
            }
            else
            {
                is_reconnect = 0;
            }
        } while (cnt > 0 && is_reconnect);
        
        if(cnt == 0)
        {
            lg(Fatal, "connect error, errno: %d, error string: %s", errno, strerror(errno));
            break;
        }


        // if(connect(sockfd, (struct sockaddr*)&server, sizeof(server)) < 0)
        // {
        //     lg(Fatal, "connect error, errno: %d, error string: %s", errno, strerror(errno));
        //     exit(CONNECT_ERR);
        // }

        
        std::cout << "Please Entry# ";
        getline(std::cin, outbuffer);

        int n = write(sockfd, outbuffer.c_str(), outbuffer.size());
        if(n < 0)
        {
            lg(Warning, "write error, errno: %d, error string: %s", errno, strerror(errno));
            // break;
        }
        

        n = read(sockfd, inbuffer, sizeof(inbuffer));
        if(n > 0)
        {
            inbuffer[n] = '\0';
            std::cout << inbuffer << std::endl;
        }
        
        close(sockfd);

    }

    

    return 0;
}